<<<<<<< HEAD
# -*- coding: utf-8 -*-
"""
    :author: HuangXiaoLong(黄小龙)
    :url: 
    :copyright:
    :license:
"""
=======

>>>>>>> 0972f4577f238b7fdb5b1129350f4a9f77333717
from flask import render_template, request, Blueprint, jsonify
from flask_babel import _
from flask_login import current_user, login_required
from collections import defaultdict
import json

from todoism.extensions import db
from todoism.models import Item, Backup
import datetime
from datetime import timedelta

todo_bp = Blueprint('todo', __name__)


@todo_bp.route('/app')
@login_required
def app():
    all_count = Item.query.with_parent(current_user).count()
    active_count = Item.query.with_parent(current_user).filter_by(done=False).count()
    completed_count = Item.query.with_parent(current_user).filter_by(done=True).count()
    return render_template('_app.html', items=current_user.items,
                           all_count=all_count, active_count=active_count, completed_count=completed_count)


@todo_bp.route('/items/new', methods=['POST'])
@login_required
def new_item():
    # 更详细的请求内容检查
    print("Request content type:", request.content_type)
    print("Request body:", request.get_data(as_text=True))
    
    # 确保是JSON请求并正确解析
    if not request.is_json:
        return jsonify(message=_('Content-Type must be application/json')), 400
        
    data = request.get_json()
    print("Parsed JSON data:", data)
    
    if data is None:
        return jsonify(message=_('Invalid JSON data')), 400
    
    if 'body' not in data or data.get('body', '').strip() == '':
        return jsonify(message=_('Item body is required')), 400

    # Ensure order field is initialized as integer
    try:
        order_value = int(data.get('order', 0))
    except (TypeError, ValueError):
        order_value = 0
        
    # Get category information, default to "Other"
    category = data.get('category', 'Other')
    if category not in ['Work', 'Life', 'Study', 'Game', 'Other']:
        category = 'Other'

    item = Item(body=data['body'], 
                author_id=current_user.id,
                category=category,
                order=order_value)  # Default to 0 if not provided or invalid

    if 'deadline' in data and data['deadline']:
        try:
            # 处理前端发送的日期时间字符串
            deadline_str = data['deadline']
            if 'T' in deadline_str:
                # 使用dateutil解析日期时间
                from dateutil import parser
                # 确保时区正确处理 - 前端已经处理了时区偏移
                # 如果字符串没有指定时区信息，视为本地时间
                item.deadline = parser.parse(deadline_str)
                
                # 打印日期时间信息以便调试
                print(f"解析的截止时间: {item.deadline}")
            else:
                return jsonify(message=_('Invalid deadline format.')), 400
        except (ValueError, KeyError) as e:
            print(f"解析日期时间出错: {str(e)}")
            return jsonify(message=_('Invalid deadline format.')), 400

    db.session.add(item)
    # 确保不使用due_date字段，因为数据库中不存在
    try:
        db.session.commit()
        return jsonify(html=render_template('_item.html', item=item), message='+1')
    except Exception as e:
        db.session.rollback()
        return jsonify(message=_('Database error: {}').format(str(e))), 500


@todo_bp.route('/item/<int:item_id>/edit', methods=['PUT'])
@login_required
def edit_item(item_id):
    item = Item.query.get_or_404(item_id)
    if current_user != item.author:
        return jsonify(message=_('Permission denied.')), 403

    data = request.get_json()
    if data is None or data['body'].strip() == '':
        return jsonify(message=_('Invalid item body.')), 400
    
    # 只更新任务内容，保留原有分类
    item.body = data['body']
    
    # 如果请求中包含分类信息，忽略它
    # 分类创建后不可修改
    
    db.session.commit()
    return jsonify(message=_('Item updated. Category cannot be changed after creation.'))


@todo_bp.route('/item/<int:item_id>/toggle', methods=['PATCH'])
@login_required
def toggle_item(item_id):
    item = Item.query.get_or_404(item_id)
    if current_user != item.author:
        return jsonify(message=_('Permission denied.')), 403

    item.done = not item.done
    db.session.commit()
    return jsonify(message=_('Item toggled.'))


@todo_bp.route('/item/<int:item_id>/delete', methods=['DELETE'])
@login_required
def delete_item(item_id):
    item = Item.query.get_or_404(item_id)
    if current_user != item.author:
        return jsonify(message=_('Permission denied.')), 403

    db.session.delete(item)
    db.session.commit()
    return jsonify(message=_('Item deleted.'))


@todo_bp.route('/item/clear', methods=['DELETE'])
@login_required
def clear_items():
    # 清除所有任务，不仅是已完成的
    items = Item.query.with_parent(current_user).all()
    for item in items:
        db.session.delete(item)
    db.session.commit()
    return jsonify(message=_('All tasks cleared!'))


@todo_bp.route('/statistics')
@login_required
def get_statistics():
    """获取任务统计数据，按类别分组，提供已完成和未完成的数量"""
    # 获取当前用户的所有任务
    items = Item.query.with_parent(current_user).all()
    
    # 初始化统计数据结构
    statistics = defaultdict(lambda: {'completed': 0, 'active': 0})
    
    # 统计每个类别的已完成和未完成任务数量
    for item in items:
        category = item.category
        if item.done:
            statistics[category]['completed'] += 1
        else:
            statistics[category]['active'] += 1
    
    # 转换为前端友好的格式
    result = {
        'categories': [],
        'completed': [],
        'active': []
    }
    
    for category, counts in statistics.items():
        result['categories'].append(category)
        result['completed'].append(counts['completed'])
        result['active'].append(counts['active'])
    
    return jsonify(result)


@todo_bp.route('/upcoming-tasks')
@login_required
def get_upcoming_tasks():
    """获取即将到期的任务（不足两小时）"""
    # 计算当前时间和两小时后的时间
    now = datetime.datetime.now()
    two_hours_later = now + timedelta(hours=2)
    
    # 查询未完成且截止时间在两小时内的任务
    upcoming_tasks = Item.query.with_parent(current_user)\
        .filter_by(done=False)\
        .filter(Item.deadline.isnot(None))\
        .filter(Item.deadline <= two_hours_later)\
        .filter(Item.deadline >= now)\
        .all()
    
    # 格式化返回数据
    tasks_data = []
    for task in upcoming_tasks:
        # 计算剩余时间（分钟）
        remaining_time = (task.deadline - now).total_seconds() // 60
        
        tasks_data.append({
            'id': task.id,
            'body': task.body,
            'category': task.category,
            'deadline': task.deadline.strftime('%Y-%m-%d %H:%M'),
            'remaining_minutes': int(remaining_time)
        })
    
    return jsonify({
        'count': len(tasks_data),
        'tasks': tasks_data
    })


# 备份和恢复功能接口
@todo_bp.route('/backups', methods=['GET'])
@login_required
def get_backups():
    """获取用户的所有备份"""
    backups = Backup.query.with_parent(current_user)\
        .order_by(Backup.timestamp.desc())\
        .all()
    
    backups_data = []
    for backup in backups:
        backups_data.append({
            'id': backup.id,
            'created_time': backup.created_time
        })
    
    return jsonify({
        'backups': backups_data
    })


@todo_bp.route('/backup/create', methods=['POST'])
@login_required
def create_backup():
    """创建一个新的备份"""
    # 获取当前用户的所有任务
    items = Item.query.with_parent(current_user).all()
    
    # 创建新备份
    backup = Backup(user_id=current_user.id)
    backup.save_items(items)
    db.session.add(backup)
    
    # 检查备份数量是否超过10个
    max_backups = 10
    current_backups = Backup.query.with_parent(current_user).count()
    
    # 如果已经有10个备份，删除最旧的一个
    warning_message = ""
    if current_backups >= max_backups:
        oldest_backup = Backup.query.with_parent(current_user)\
            .order_by(Backup.timestamp).first()
        db.session.delete(oldest_backup)
        warning_message = _("Maximum number of backups reached. The oldest backup has been deleted.")
    
    db.session.commit()
    
    return jsonify({
        'id': backup.id,
        'created_time': backup.created_time,
        'message': _('Backup created successfully.'),
        'warning': warning_message
    })


@todo_bp.route('/backup/<int:backup_id>/restore', methods=['POST'])
@login_required
def restore_backup(backup_id):
    """从备份恢复任务"""
    # 获取指定备份
    backup = Backup.query.get_or_404(backup_id)
    
    # 权限检查
    if backup.user_id != current_user.id:
        return jsonify(message=_('Permission denied.')), 403
    
    try:
        # 解析备份数据
        backup_data = json.loads(backup.data)
        
        # 删除当前所有任务
        current_items = Item.query.with_parent(current_user).all()
        for item in current_items:
            db.session.delete(item)
        
        # 从备份创建新任务
        for item_data in backup_data:
            item = Item(
                body=item_data['body'],
                done=item_data['done'],
                category=item_data['category'],
                order=item_data['order'],
                author_id=current_user.id
            )
            
            # 处理截止时间
            if item_data['deadline']:
                from dateutil import parser
                item.deadline = parser.parse(item_data['deadline'])
            
            db.session.add(item)
        
        db.session.commit()
        
        return jsonify({
            'message': _('Backup restored successfully.'),
            'timestamp': backup.created_time
        })
    
    except Exception as e:
        db.session.rollback()
        return jsonify(message=_('Failed to restore backup: {}').format(str(e))), 500


@todo_bp.route('/backup/<int:backup_id>', methods=['DELETE'])
@login_required
def delete_backup(backup_id):
    """删除指定备份"""
    backup = Backup.query.get_or_404(backup_id)
    
    # 权限检查
    if backup.user_id != current_user.id:
        return jsonify(message=_('Permission denied.')), 403
    
    db.session.delete(backup)
    db.session.commit()
    
    return jsonify(message=_('Backup deleted.'))
